#pragma once
#include "Mesh.h"

class FnSurfaceHarmonicParam
{
public:
  FnSurfaceHarmonicParam(Mesh& _mesh);
  ~FnSurfaceHarmonicParam(void);

  const Mesh& mesh() const        { return  mesh_; }
  Mesh& mesh()                    { return  mesh_; }


  void  init();
  void  calc();
  int   calc_with_taucs();

  void  set_side_index(int _side_idx)     { side_idx_ = _side_idx; }
  int   get_side_index() const            { return  side_idx_; }

  void  set_side_corner_vertices(const std::vector<int>& _vtx_indices);

  Scalar cot_weight(const Mesh::EdgeHandle _eh) const;

  void  set_weight_type(WeightType _type)      { weight_type_ = _type; }
  WeightType weight_type()                     { return  weight_type_; }


  Scalar cot(const Mesh::HalfedgeHandle _corner) const;

  void  export_linear_system(const std::string& _A_dat, const std::string& _b_dat);

  void  save(const std::string& _filename);
  

  // aux info
public:
	static int  nx0_face_side_idx;
	static int  px0_face_side_idx;
	static int  ny_face_side_idx;
	static int  py_face_side_idx;
	static int  nz0_face_side_idx;
	static int  pz0_face_side_idx;    
	static int  nx1_face_side_idx;
	static int  px1_face_side_idx;
	static int  nz1_face_side_idx;
	static int  pz1_face_side_idx;    

	//int nSides;


private:
  Mesh&       mesh_;
  WeightType  weight_type_;
  std::vector<Mesh::VertexHandle>   square_corner_vertices_;
  int         side_idx_;

  
  OpenVolMesh::VPropHandleT<int>          vprop_lns_idx_;     // indices in the linear system
  
  OpenVolMesh::VPropHandleT<Param>        vprop_param_;
  OpenVolMesh::EPropHandleT<Scalar>       eprop_w_;
  OpenVolMesh::FPropHandleT<int>          fprop_side_idx_;
  OpenVolMesh::VPropHandleT<VertexType>   vprop_type_;
  OpenVolMesh::EPropHandleT<EdgeType>     eprop_type_;
};
